package com.hexun.vmcenter.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hexun.vmcenter.service.RateHandler;
import com.hexun.vmcenter.service.RedisService;
import com.hexun.vmcenter.util.Rate;

@Service("rateHandler")
public class RateHandlerImpl implements RateHandler {

	@Autowired
	private RedisService redisService;

	private static final Logger log = LoggerFactory.getLogger(RateHandlerImpl.class);

	public void insert(String requestMethod, long timestamp, boolean increment, Rate rate) throws Exception {
		int diff = 1;
		int clock = 1;
		if (rate == Rate.SECOND) {
			diff = diff * 100; // 100毫秒/Bucket
			clock = clock * 1; // 定时1秒钟
		} else if (rate == Rate.MINUTE) {
			diff = diff * 1000; // 1秒/Bucket
			clock = clock * 60; // 定时一分钟
		} else if (rate == Rate.HOUR) {
			diff = diff * 1000 * 60; // 1分钟/Bucket
			clock = clock * 60 * 60; // 定时一小时
		} else if (rate == Rate.DAY) {
			diff = diff * 1000 * 60 * 60; // 一小时/Bucket
			clock = clock * 60 * 60 * 24; // 定时一天
		}

		timestamp = timestamp / diff; // 换算Bucket

		String key = requestMethod + timestamp;
		try {
			if (redisService.get(key, "0") != null && increment) {
				redisService.incrBy(key, 1);
				redisService.expire(key, clock);
				System.out.println("incrBy");
			} else {
				System.out.println(clock);
				System.out.println("set");
				redisService.set(key, "1", clock);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}

	public boolean isLimit(String requestMethod, long currentTime, int number, Rate rate) throws Exception {
		insert(requestMethod, currentTime, true, rate);

		// 把求和的方法合并进来，优化时间
		int diff = 1; // 作被除数（将当前时间换算成对应的Bucket）
		int size = 1; // 应该向前取多大的区间范围
		if (rate == Rate.SECOND) {
			diff = diff * 100; // 100毫秒/Bucket
			size = size * 10; // 向前找10个bucket
		} else if (rate == Rate.MINUTE) {
			diff = diff * 1000; // 1秒/Bucket
			size = size * 60; // 向前找60个bucket
		} else if (rate == Rate.HOUR) {
			diff = diff * 1000 * 60; // 1分钟/Bucket
			size = size * 60; // 向前找10个bucket
		} else if (rate == Rate.DAY) {
			diff = diff * 1000 * 60 * 60; // 一小时/Bucket
			size = size * 24; // 向前找10个bucket
		}

		currentTime = currentTime / diff; // 换算Bucket

		int sum = 0;

		for (int i = 0; i < size; i++) {
			long bucket = currentTime - i;
			String count = redisService.get(requestMethod + bucket, "0");
			sum = sum + Integer.parseInt(count);
			if (sum > number) {
				return true;
			}
		}
		return false;
	}

}
